package com.ruoyi.web.controller.client;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.GetUserId;
import com.ruoyi.common.enums.OperatorType;
import com.ruoyi.common.enums.RequestType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.responseBodyJson.JSON;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.yf.domain.*;
import com.ruoyi.yf.domain.mobile.YfAppRemind;
import com.ruoyi.yf.service.*;
import com.ruoyi.yf.tool.barcode.Rules;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * LXL
 * 接口 - 批量医废录入APP
 */
@RequestMapping("/client/yfbatch")
@RestController
@Api(tags = "接口-批量医废录入APP")
public class ClientYFBatchController extends BaseController {

    @Autowired
    private IYfTagService yfTagService;

    @Autowired
    private IYfClientVersionService yfClientVersionService;

    @Autowired
    private IYfStorageWarningService yfStorageWarningService;

    @Autowired
    private IYfOutstoreRecordService yfOutstoreRecordService;

    @Autowired
    private IYfDeptService yfDeptService;

    @Autowired
    private ISysDictDataService dictDataService;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


    // 查询app最新版本
    //8b7b88af-49bb-4bf7-a8ef-afc6d3477f84
    @ApiOperation(value = "接口-查询app最新版本")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "app类型", type = "String", required = true),
            @ApiImplicitParam(name = "updateRegion", value = "更新地区", type = "String", required = true)
    })
    @RequestMapping(method = RequestMethod.POST, value = "/getAppVersion")
    public YfClientVersion getAppVersion(String type, String updateRegion) {
        YfClientVersion yfcv = yfClientVersionService.getAppVersionByCondition(type, updateRegion);
        return yfcv;
    }


    /**
     *  获取用户所在医院的科室（包括标准科室代码） , 获取医废类型
     *  d9ebf80f-b4a5-493c-8653-7f579cf10442
     */
    @ApiOperation(value = "获取科室和医废类型", notes = "获取科室和医废类型")
    @RequestMapping(method = RequestMethod.POST, value = "/getKSListAndYFTypeList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "groupNo", value = "分组编号", dataType = "String", required = false)
    })
    public HashMap<String,Object> getKSListAndYFTypeList(Long uid, String groupNo) {
        HashMap<String,Object> hashMap = new HashMap<>();
        if (uid == null) {
            TableDataInfo dataTable = new TableDataInfo();
            dataTable.setMsg("请检查uid参数");
            dataTable.setCode(1001);
            hashMap.put("dataTable",dataTable);
            return hashMap;
        }
        // 获取科室及对应的标准科室
        List<YfDept> deptlist = yfDeptService.getDepartmentAndStandardDeptByUserId(uid);
        // 获取医废类型不包括胎盘
        List<SysDictData> dictDatalist = dictDataService.yfTypeNoTP();
        hashMap.put("kSList",getDataTable(deptlist));
        hashMap.put("yFTypeList",getDataTable(dictDatalist));

        return hashMap;
    }


    // 查询已入库医废列表
    //b7f69606-320d-469c-ac8f-e8eaf1167dc4
    @ApiOperation(value = "接口-查询已入库医废列表")
    @RequestMapping(method = RequestMethod.POST, value = "/selectInpSM")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "hid", value = "医院id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "sid", value = "暂存点id", dataType = "Long", required = true)
    })
    @JSON(type = YfTag.class, include = "codeid,bag,outBag,trashType,trashTypeName,weight,outWeight,intoUserId,intoUserName,intoDate,trashStatus")
    @Log(title = "接口-查询已入库医废列表", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public TableDataInfo<List<YfTag>> selectInpSM(Long uid,Long hid,Long sid) {
        if( uid == null || hid == null || sid == null  ){
            return getDataTable(new ArrayList<>());
        }
        List<YfTag> list = yfTagService.selectInpSM(uid);
        return getDataTable(list);
    }

    // 查询未出库完成的医废列表
    //536ddc62-b849-4a06-bc32-2d5049728f79
    @ApiOperation(value = "接口-查询未出库完成的医废列表")
    @RequestMapping(method = RequestMethod.POST, value = "/getNoOutStoreCompleteYF")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "hid", value = "医院id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "sid", value = "暂存点id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "ksid", value = "科室id", dataType = "Long", required = false),
    })
    @JSON(type = YfTag.class, include = "codeid,bag,outBag,trashType,sourceDeptId,standardDeptCode,trashTypeName,weight,outWeight,intoUserId,intoUserName,intoDate,trashStatus")
    @Log(title = "接口-查询未出库完成的医废列表", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public TableDataInfo<List<YfTag>> getNoOutStoreCompleteYF(Long uid,Long hid,Long sid,Long ksid) {
        if( uid == null || hid == null || sid == null ){
            return getDataTable(new ArrayList<>());
        }
        List<YfTag> list = yfTagService.getNoOutStoreCompleteYF(sid,ksid);       // 按暂存点查医废状态是20或25的
        return getDataTable(list);
    }


    // 查询已出库医废列表
    //63c4da26-a827-48f3-ab64-e6cb98bf92c5
    @ApiOperation(value = "接口-查询已出库医废列表")
    @ApiImplicitParam(name = "uid", value = "用户id", dataType = "YfTag")
    @RequestMapping(method = RequestMethod.POST, value = "/selectOutSM")
    @JSON(type = YfTag.class, include = "codeid,bag,outBag,trashType,trashTypeName,sourceDeptId,weight,outWeight,intoUserId,intoUserName,intoDate,outUserId,outUserName,outDate,trashStatus")
//    @Log(title = "接口-查询已出库医废列表", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
//            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public TableDataInfo<List<YfTag>> selectOutSM(Long uid) {
        List<YfTag> list = yfTagService.selectOutSM(uid);
        return getDataTable(list);
    }


    // 按条件查询医废历史记录
    //637da63f-9c92-44ab-9a2c-4bf8ac9a5bed
    @ApiOperation(value = "接口-查询医废历史记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页数", type = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", type = "Integer", required = true),
            @ApiImplicitParam(name = "userId", value = "用户id", type = "Long", required = true),
            @ApiImplicitParam(name = "stagingId", value = "暂存点id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "yftype", value = "医废类型value", dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String")
    })
    @RequestMapping(method = RequestMethod.POST, value = "/getYFRecordByCondition")
    @JSON(type = YfTag.class, include = "codeid,bag,trashType,trashTypeName,sourceDeptId,weight,intoUserId,intoUserName,intoDate,outUserId,outUserName,outDate,trashStatus,trashStatusName")
    public TableDataInfo<List<YfTag>> getYFRecordByCondition(Integer pageNo, Integer pageSize, Long userId, Long stagingId, String yftype, String startDate, String endDate) {
        if (pageNo == null || pageNo == 0 || pageSize == null || pageSize == 0 || userId == null || userId == 0 || stagingId == null || stagingId == 0) {
            return getDataTable(new ArrayList<YfTag>());
        }
        List<YfTag> list = yfTagService.getYFRecordByCondition(pageNo, pageSize, userId, stagingId, yftype, startDate, endDate);
        return getDataTable(list);
    }


    // 查询医院医废统计报表
    //d57105f6-42b0-4747-8bac-2df421cd4370
    @ApiOperation(value = "接口-查询医院医废统计报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", type = "Long", required = true),
            @ApiImplicitParam(name = "hospitalId", value = "医院id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String")
    })
    @RequestMapping(method = RequestMethod.POST, value = "/getYFSatisticalByHospitalId")
    @JSON(type = YfTag.class, include = "trashType,trashTypeName,bag,weight")
    @Log(title = "接口-查询医院医废统计报表", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.USERID)
    public TableDataInfo<List<YfTag>> getYFSatisticalByHospitalId(Long userId,Long hospitalId,String startDate,String endDate){
        List<YfTag> list = yfTagService.getYFSatisticalByHospitalId(userId, hospitalId, startDate, endDate);
        return getDataTable(list);
    }


    // 今天无医废录入
    //c1114645-94a5-4e90-a66f-174ac53fa35a
    @ApiOperation(value = "接口-今天无医废录入")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", type = "Long", required = true),
            @ApiImplicitParam(name = "stagingId", value = "医院id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "hospitalId", value = "暂存点id", dataType = "Long", required = true)
    })
    @RequestMapping(method = RequestMethod.POST, value = "/todayNoYF")
    @Log(title = "接口-今天无医废录入", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.USERID)
    public AjaxResult todayNoYF(Long userId,Long stagingId,Long hospitalId) {
        if (userId == null || stagingId == null || hospitalId == null ) {
            return AjaxResult.success("填报成功！");
        }
        int i = yfDeptService.todayNoYF(stagingId);
        if (i < 0)
            return AjaxResult.error("填报失败！");
        return AjaxResult.success("填报成功！");
    }


    // 提交多条医废接口 -- 批量
    //bcb7063d-0cd9-408e-b7a6-2fe18ea02845
    @ApiOperation(value = "接口-提交多条医废")
    @ApiImplicitParam(name = "yfTag", value = "对象", dataType = "YfTag", allowMultiple = true)
    @RequestMapping(method = RequestMethod.POST, value = "/uploadSM")
    @Log(title = "接口-提交多条医废", businessType = BusinessType.INSERT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.JSON, getUserId = GetUserId.JSONMOREYFTAG)
    public AjaxResult newupload(@RequestBody List<YfTag> tags) {
        Date date = new Date();
        for (int i = 0; i < tags.size(); i++) {
            tags.get(i).setCodeid(new Rules().longBarcode()); // 条码
            tags.get(i).setTrashStatus("20");
            tags.get(i).setCollectUpdateDate(date);
            tags.get(i).setIntoDate(date);
            tags.get(i).setCreateTime(date);
            tags.get(i).setUpdateTime(date);
            tags.get(i).setUpdateWay("3");
        }
        // int i = yfTagService.insertYfTagList(tags);
        int i = yfTagService.insertBatchYfTagList(tags);
        if (i < 0)
            return AjaxResult.error("入库失败！");
        return AjaxResult.success("入库成功！");
    }


    // 接口-批量整批医废出库
    //5d4d402f-025c-4542-a22b-9fe15f2363bb
    @ApiOperation(value = "接口-批量整批医废出库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户id", type = "Long", required = true),
            @ApiImplicitParam(name = "ids", value = "出库id", dataType = "String", allowMultiple = true, required = true)
    })
    @RequestMapping(method = RequestMethod.POST, value = "/updateSMS")
    @Log(title = "接口-批量整批医废出库", businessType = BusinessType.UPDATE, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public AjaxResult updateSMS(Long uid, String[] ids) {
        int i = yfTagService.updateSMS(uid, ids);
        if (i < 0)
            return AjaxResult.error("出库失败！");
        return AjaxResult.success("出库成功！");
    }


    // 接口-批量医废出库(可部分出库)
    //f6f4c37b-e12b-410b-bdd3-a020f92dbebd
    @ApiOperation(value = "接口-批量医废出库(可部分出库)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "用户id", type = "Long", required = true),
            @ApiImplicitParam(name = "userName", value = "用户姓名", type = "String", required = true),
            @ApiImplicitParam(name = "hid", value = "医院id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "sid", value = "暂存点id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "yfjson", value = "出库医废json", dataType = "String", required = true),
    })
    @RequestMapping(method = RequestMethod.POST, value = "/savePartOutStoreYF")
    @Log(title = "接口-批量医废出库(可部分出库)", businessType = BusinessType.UPDATE, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public AjaxResult savePartOutStoreYF(Long uid,String userName, Long hid, Long sid,String yfjson) {
        if( uid == null || hid == null || sid == null || StringUtils.isEmpty(userName) || StringUtils.isEmpty(yfjson) ){
            return AjaxResult.error("出库失败！");
        }
        // json转list
        List<YfTag> yfList = JSONObject.parseArray(yfjson, YfTag.class);
        // 需update的字段：加到已出库袋数、加到已出库重量、医废状态25或30、出库人、出库时间、update_time
        List<YfTag> zyfList = new ArrayList<>();
        List<YfOutstoreRecord> outrecordList = new ArrayList<>();      // 出库历史记录
        for (int i = 0; i < yfList.size(); i++) {
//            System.out.println( yfList.get(i).getCodeid() + "  已出库：    " + (  yfList.get(i).getOutBag() )  );
//            System.out.println( yfList.get(i).getCodeid() + "  未出库：    " + ( yfList.get(i).getBag() - yfList.get(i).getOutBag() )  );
//            System.out.println( yfList.get(i).getCodeid() + "  本次出库袋数：  " + ( yfList.get(i).getThisTimeOutBag() )  );
//            System.out.println( yfList.get(i).getCodeid() + "  本次出库重量：  " + ( yfList.get(i).getThisTimeOutWeight() )  );

            if( yfList.get(i).getThisTimeOutBag() == null || yfList.get(i).getThisTimeOutBag().longValue() == 0
                    || yfList.get(i).getThisTimeOutWeight() == null || yfList.get(i).getThisTimeOutWeight().doubleValue() == 0 ){
                continue;
            }

            // 本次出库重量格式化
            BigDecimal ttOutWeightFormat =  new BigDecimal( yfList.get(i).getThisTimeOutWeight().doubleValue() )
                    .setScale(2,BigDecimal.ROUND_HALF_UP);
            // 总重量
            BigDecimal weightFormat = new BigDecimal( yfList.get(i).getWeight().doubleValue() )
                    .setScale(2,BigDecimal.ROUND_HALF_UP);
            // 已出库重量
            BigDecimal outWeightFormat = new BigDecimal( yfList.get(i).getOutWeight().doubleValue() )
                    .setScale(2,BigDecimal.ROUND_HALF_UP);

            String isAllOutStore = "0";
            // 总重量 - 已出库重量 = 本次出库重量时 ： 整条医废全部出完  修改医废状态
            if( ttOutWeightFormat.doubleValue() >= weightFormat.subtract(outWeightFormat).doubleValue() ){
                yfList.get(i).setThisTimeOutWeight( weightFormat.subtract(outWeightFormat).doubleValue() );
                yfList.get(i).setTrashStatus("30");
                isAllOutStore = "1";
            }else{
                yfList.get(i).setTrashStatus("25");
            }
            if( yfList.get(i).getThisTimeOutBag().longValue() >= yfList.get(i).getBag().longValue() - yfList.get(i).getOutBag().longValue() ){
                yfList.get(i).setThisTimeOutBag( yfList.get(i).getBag().longValue() - yfList.get(i).getOutBag().longValue() );
            }
            yfList.get(i).setOutUserId(uid);    // 出库人id

            // 添加到要提交的医废list、添加到出库历史纪录
            zyfList.add( yfList.get(i) );
            outrecordList.add( new YfOutstoreRecord( yfList.get(i).getCodeid(),hid,sid,yfList.get(i).getTrashType(),
                    yfList.get(i).getThisTimeOutBag(),yfList.get(i).getThisTimeOutWeight(),isAllOutStore,uid,userName) );
        }
        // 保存部分出库医废list、部分医废(一批医废一次未出完)出库记录
        int i = 0;
        if( !zyfList.isEmpty() ){
            i = yfTagService.savePartOutStoreYF(zyfList);
        }
        yfOutstoreRecordService.saveOutRecordList(outrecordList);

        if (i < 0) {
            return AjaxResult.error("出库失败！");
        }
        return AjaxResult.success("出库成功！");
    }



    // 预警提醒
    //bac8ef90-e696-4e35-8208-e59d3c061c93
    @ApiOperation(value = "接口-预警提醒")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hid", value = "医院id", type = "Long", required = true),
            @ApiImplicitParam(name = "sid", value = "暂存点id", type = "Long", required = true),
            @ApiImplicitParam(name = "uid", value = "用户id", type = "Long", required = true)
    })
    @RequestMapping(method = RequestMethod.POST, value = "/getRemind")
    @Log(title = "接口-预警提醒", businessType = BusinessType.SELECT, operatorType = OperatorType.MOBILE,
            requestType = RequestType.KEYVALUE, getUserId = GetUserId.UID)
    public List<YfAppRemind> getRemind(Long hid, Long sid, Long uid) throws ParseException {
        List<YfAppRemind> list = new ArrayList<>();
        if( hid == null || sid == null || uid == null ){
            return list;
        }
        List<YfHospitalStatus> yfhslist = yfStorageWarningService.hospitalStatus(hid);   // 医院id
        if( yfhslist == null || yfhslist.isEmpty() ){
            return list;
        }
        YfHospitalStatus yfhs = null;
        for (int i = 0; i < yfhslist.size(); i++) {
            if( yfhslist.get(i).getStagingId().longValue() == sid.longValue() ){
                yfhs = yfhslist.get(i);
                break;
            }
        }
        if( yfhs == null ){
            return list;
        }
        // 预警值
        if( yfhs.getMaxStore() != null && yfhs.getMaxStore().doubleValue() != 0.0
                && yfhs.getInStoreWeight() != null && yfhs.getInStoreWeight().doubleValue() != 0.0 ){
            if( yfhs.getInStoreWeight().doubleValue() > yfhs.getMaxStore().doubleValue() ){
                list.add(new YfAppRemind(3, "医废暂存超量预警", "预警值" + yfhs.getMaxStore().doubleValue()
                        + "Kg，目前暂存量" + yfhs.getInStoreWeight().doubleValue() + "Kg"));
            }
        }
        // 超期未录入预警    0 开    1关
        if( yfhs.getOverdueNotinputSwitch().equals("0")  && yfhs.getOverdueNotinputHours() != null && yfhs.getOverdueNotinputHours().intValue() != 0 ){
            long overdueTime = 3600000L * (yfhs.getOverdueNotinputHours().intValue() + 24);
            if( yfhs.getLastCollDate() != null ){    // 有最后一次收集时间才比较，没有收集不预警
                // 处理最后一次收集时间取到天转成long型
                String lastCollDate = sdf.format(yfhs.getLastCollDate());
                if( (new Date().getTime() - sdf.parse(lastCollDate).getTime()) > overdueTime ){ // 最后一次收集时间超过设置的预警时间

                    if( yfhs.getLastNoCollDate()== null ||
                            ( yfhs.getLastNoCollDate()!= null
                                    && (new Date().getTime() - sdf.parse( sdf.format(yfhs.getLastNoCollDate())).getTime()) > overdueTime ) ){  // 如果昨天报了无医废录入时间也不报警
                        list.add(new YfAppRemind(1, "超期未录入预警", "超过"
                                + yfhs.getOverdueNotinputHours().intValue() + "小时无医废入库"));
                    }
                }
            }else if( yfhs.getStagingCreateTime() != null ){     // 如果没有录入过医废，取暂存点创建时间
                // 处理最后一次收集时间取到天转成long型
                String stagingCreateTime = sdf.format(yfhs.getStagingCreateTime());
                if( (new Date().getTime() - sdf.parse(stagingCreateTime).getTime()) > overdueTime ){
                    if( yfhs.getLastNoCollDate()== null ||
                            ( yfhs.getLastNoCollDate()!= null
                                    && (new Date().getTime() - sdf.parse( sdf.format(yfhs.getLastNoCollDate())).getTime()) > overdueTime ) ){  // 如果昨天报了无医废录入时间也不报警
                        list.add(new YfAppRemind(1, "超期未录入预警", "超过"
                                + yfhs.getOverdueNotinputHours().intValue() + "小时无医废入库"));
                    }
                }
            }
        }
        // 超期未出库预警
        if( yfhs.getNoOutBag() != null && yfhs.getNoOutBag().longValue() > 0
                && yfhs.getNoOutWeight() != null && yfhs.getNoOutWeight().doubleValue() > 0.0 ){
            // 根据暂存点查询超过48小时未出库的科室
            String ksnames = yfStorageWarningService.getKsNamesByStangId(yfhs.getStagingId());
            if( !StringUtils.isEmpty(ksnames) ){
                ksnames = ksnames + "，";
            }else{
                ksnames = "";
            }
            list.add(new YfAppRemind(2, "超期未出库预警", ksnames + "共计：" + yfhs.getNoOutBag().longValue()
                    + "袋医废，" + " 重量：" + yfhs.getNoOutWeight().doubleValue() + "kg，超过48小时未出库"));
        }

        return list;
    }



}
